#include "IRControl.h"
#include "generated/gui_guider.h"
#include "Button2.h"
// Constants
const uint16_t kRecvPin = 35;
const uint16_t kIrLedPin = 4;
const uint16_t kCaptureBufferSize = 1024;
const uint8_t kTimeout = 50;
const uint16_t kFrequency = 38000;
extern Button2 Button_middle;
// Global variables
bool init_IR_REC = false;

// IR Transmitter and Receiver
IRsend irsend(kIrLedPin);
IRrecv irrecv(kRecvPin, kCaptureBufferSize, kTimeout, false);
decode_results results;
extern Preferences preferences;


void update_list_item_text(lv_ui *ui,uint8_t index, const char *new_text) {
    lv_obj_t *item = NULL;

    switch(index) {
        case 0:
            item = ui->IR_PAGE_list_IR_item0;
            break;
        case 1:
            item = ui->IR_PAGE_list_IR_item1;
            break;
        case 2:
            item = ui->IR_PAGE_list_IR_item2;
            break;
        case 3:
            item = ui->IR_PAGE_list_IR_item3;
            break;
        case 4:
            item = ui->IR_PAGE_list_IR_item4;
            break;
        case 5:
            item = ui->IR_PAGE_list_IR_item5;
            break;
        case 6:
            item = ui->IR_PAGE_list_IR_item6;
            break;
        case 7:
            item = ui->IR_PAGE_list_IR_item7;
            break;
        default:
            return; // 如果索引超出范围，直接返回
    }

    lv_obj_t *label = lv_obj_get_child(item, 0);
    if (label != NULL) {
        lv_label_set_text(label, new_text);
    }
}

void processDescription(const String& description, char* outputArray, int maxLength) {
    String result = "";
    int pos = 0;
    int charCount = 0;

    while (pos < description.length() && charCount < 60) {
        if ((description[pos] & 0x80) != 0) {
            // This is likely a multi-byte character (e.g., Chinese)
            if (pos + 2 < description.length()) {
                String currentChar = description.substring(pos, pos + 3);
                
                // Check if this character is part of "模式"
                if (currentChar != "模" && currentChar != "式") {
                    result += currentChar;
                    charCount++;
                }
                
                pos += 3;
            } else {
                break; // Not enough bytes left for a full character
            }
        } else {
            // This is an ASCII character
            result += description[pos];
            charCount++;
            pos++;
        }

        // Check for "模式" in the result and remove it
        int modePos = result.indexOf("模式");
        if (modePos != -1) {
            result.remove(modePos, 6); // Remove "模式" (6 bytes)
            charCount -= 2; // Decrease character count by 2
        }
    }

    // Trim any trailing spaces
    result.trim();

    // Convert result to char array
    result.toCharArray(outputArray, maxLength);
}



void initIR() {

    irsend.begin();
}

void readData(int storageIndex, String* protocols, char* description) {
    preferences.begin("IR", true);
    String protocolsKey = "protocols" + String(storageIndex);
    String descriptionKey = "description" + String(storageIndex);
    // 读取协议字符串
    *protocols = preferences.getString(protocolsKey.c_str(), "");
    // 读取描述字符串
    String desc = preferences.getString(descriptionKey.c_str(), "");
    desc.toCharArray(description, desc.length() + 1);
    preferences.end();
}

void update_lvgl(lv_ui *ui, uint8_t index, const char *outputArray, const char *protocol) {
    // Create a buffer to hold the combined string
    char new_text[100];  // Adjust size as needed

    // Extract the first four letters of the protocol
    char protocol_prefix[5];  // 4 letters + null terminator
    strncpy(protocol_prefix, protocol, 4);
    protocol_prefix[4] = '\0';  // Null-terminate the string

    // Combine the protocol prefix and the outputArray element
    snprintf(new_text, sizeof(new_text), "%s %s", protocol_prefix, outputArray);

    // Call the update function
    update_list_item_text(ui, index, new_text);

}

void processAndStore(int storageIndex) {

    char outputArray[100]; // 确保数组足够大
    if (storageIndex < 0 || storageIndex >= 10) {
        Serial.println("Invalid storage index. Must be between 0 and 9.");
        return;
    }
 
Serial.println("等待学习");
    if (!init_IR_REC) {
        irrecv.enableIRIn();
        init_IR_REC = true;
    }
    unsigned long startTime = millis();
    while (!irrecv.decode(&results)) {
        if (millis() - startTime > 10000 || digitalRead(16) == 0 ) {
            Serial.println("Timeout: No IR signal received.");
            lv_imgbtn_set_state(guider_ui.IR_PAGE_flag, LV_BTN_STATE_PRESSED);
            lv_obj_set_hidden(guider_ui.IR_PAGE_flag, false);
		    lv_obj_set_hidden(guider_ui.IR_PAGE_waitflag, true);
		    lv_obj_set_hidden(guider_ui.IR_PAGE_waitword, true);
            lv_task_handler(); // 调用 LVGL 的任务处理函数
            return;
        }
        lv_task_handler(); // 调用 LVGL 的任务处理函数
        delay(70);
    }
    decode_type_t protocol = results.decode_type;
    uint16_t size = results.bits;
    String description = IRAcUtils::resultAcToString(&results);
    Serial.println("Description: " + description);
    Serial.println("Description Length: " + String(description.length()));
    if (description.length()) {
        Serial.println("解码空调");
    processDescription(description, outputArray, sizeof(outputArray));
    Serial.println("Output Array: " + String(outputArray));
    Serial.println(outputArray);
     }
    preferences.begin("IR", false);
    String protocolKey = "protocol" + String(storageIndex);
    String sizeKey = "size" + String(storageIndex);
    String valueKey = "value" + String(storageIndex);
    String stateKey = "state" + String(storageIndex);
    String rawKey = "raw" + String(storageIndex);
    String protocolsKey = "protocols" + String(storageIndex);
    String descriptionKey = "description" + String(storageIndex);
    preferences.putUInt(protocolKey.c_str(), protocol);
    preferences.putUInt(sizeKey.c_str(), size);
    if (protocol == decode_type_t::UNKNOWN) {
        uint16_t *raw_array = resultToRawArray(&results);
        size = getCorrectedRawLength(&results);
        preferences.putUInt(sizeKey.c_str(), size);
        preferences.putBytes(rawKey.c_str(), raw_array, size * sizeof(uint16_t));
        delete[] raw_array;
    } else if (hasACState(protocol)) {
        uint16_t stateSize = size / 8;
        preferences.putUInt(sizeKey.c_str(), stateSize);
        preferences.putBytes(stateKey.c_str(), results.state, stateSize);
    } else {
        preferences.putULong64(valueKey.c_str(), results.value);
    }
    String protocolStr = typeToString(protocol);
    preferences.putString(protocolsKey.c_str(), protocolStr);
    if (description.length())
    preferences.putString(descriptionKey.c_str(), outputArray);
    preferences.end();
    irrecv.disableIRIn();
    init_IR_REC = false;

    //Serial.printf("IR signal stored at index %d. Protocol: %s, Size: %d\n", storageIndex, typeToString(protocol).c_str(), size);
    
     if (description.length()){
    
    update_lvgl(&guider_ui,storageIndex, outputArray, protocolStr.c_str());
     }
     else {
        outputArray[0] = 0;
        update_lvgl(&guider_ui,storageIndex, outputArray, protocolStr.c_str());
     }
     lv_imgbtn_set_state(guider_ui.IR_PAGE_flag, LV_BTN_STATE_RELEASED);
     lv_obj_set_hidden(guider_ui.IR_PAGE_flag, false);
	 lv_obj_set_hidden(guider_ui.IR_PAGE_waitflag, true);
	 lv_obj_set_hidden(guider_ui.IR_PAGE_waitword, true);
     lv_task_handler(); // 调用 LVGL 的任务处理函数
     
}

void readAndSend(int index) {
    if (index < 0 || index > 9) {
        Serial.println("Index out of range. Please use a value between 0 and 9.");
        return;
    }

    preferences.begin("IR", true);
    String protocolKey = "protocol" + String(index);
    String sizeKey = "size" + String(index);
    String valueKey = "value" + String(index);
    String stateKey = "state" + String(index);
    String rawKey = "raw" + String(index);
    uint32_t storedProtocol = preferences.getUInt(protocolKey.c_str(), 0);
    uint16_t storedSize = preferences.getUInt(sizeKey.c_str(), 0);
    bool success = false;
    if (storedProtocol != 0) {
        decode_type_t protocol = static_cast<decode_type_t>(storedProtocol);
        if (protocol == decode_type_t::UNKNOWN) {
            uint16_t *raw_array = new uint16_t[storedSize];
            preferences.getBytes(rawKey.c_str(), raw_array, storedSize * sizeof(uint16_t));
            irsend.sendRaw(raw_array, storedSize, kFrequency);
            delete[] raw_array;
            success = true;
        } else if (hasACState(protocol)) {
            uint8_t state[kStateSizeMax];
            preferences.getBytes(stateKey.c_str(), state, storedSize);
            success = irsend.send(protocol, state, storedSize);
            Serial.printf("%s\n", (const char*)state);
        } else {
            uint64_t storedValue = preferences.getULong64(valueKey.c_str(), 0);
            success = irsend.send(protocol, storedValue, storedSize);
        }
        uint32_t now = millis();
        Serial.printf(
            "%06u.%03u: A %d-bit %s message was %ssuccessfully retransmitted.\n",
            now / 1000, now % 1000, storedSize, typeToString(protocol).c_str(),
            success ? "" : "un");
    } else {
        Serial.println("No protocol stored for this index.");
    }
    preferences.end();
}
